package net.woggle.shackbrowseapi;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.*;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;

import com.google.appengine.labs.repackaged.org.json.JSONArray;
import com.google.appengine.labs.repackaged.org.json.JSONException;
import com.google.appengine.labs.repackaged.org.json.JSONObject;


@SuppressWarnings("serial")
public class Thread extends HttpServlet {
	
	static final String LOGIN_URL = "https://www.shacknews.com/account/signin";
	static final String PAGE_URL = "http://www.shacknews.com/chatty";
	static final String USER_AGENT = "shackbrowseAPI/1.0";
	
	class ReplyPost
	{
		String body;
		String category;
		String postId;
		String author;
		String date;
		int depth = 0;
	}
	
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		
		resp.setContentType("application/json; charset=UTF-8");
		
		String id = req.getParameter("id");
		
		if (id == null)
			return;
		

        //
        Document doc = Jsoup.parse(LoginDownload.get(PAGE_URL + "?id=" + id));
		
		Elements threads = doc.select("div.threads > div.root");
		
		JSONArray comments = new JSONArray();
		for (Element thisEl : threads)
		{
			ReplyPost res = new ReplyPost();
			Element fullPost = thisEl.getElementsByClass("fullpost").get(0);
			Set<String> names = fullPost.classNames();
			for (String name : names)
			{
				if (name.contains("fpmod_"))
					res.category = name.substring(6);
			}
			res.author = fullPost.getElementsByClass("user").get(0).child(0).ownText();
			res.postId = thisEl.id().substring(5);
			res.date = fullPost.getElementsByClass("postdate").get(0).ownText();
			res.body = fullPost.getElementsByClass("postbody").get(0).html();
			res.depth = 0;
			ArrayList<ReplyPost> replies = new ArrayList<ReplyPost>();
			try {
				Elements replycapcont = thisEl.getElementsByClass("capcontainer");
				if (replycapcont != null && replycapcont.size() > 0)
				{
	    			Element replycont = replycapcont.get(0).getElementsByTag("ul").get(0);
	    			replies = parseTree(replycont, 1);
				}
			}
			catch (Exception h) { resp.getWriter().println("ERROR CHECKING REPLIES" + res.postId); }
			
			// download post bodies and dates
			if (replies.size() > 0)
			{
	            //
	            doc = Jsoup.parse(LoginDownload.get("http://www.shacknews.com/frame_chatty.x?root=" + res.postId));
				
				Elements users = doc.select("li.result");
				
				for (ReplyPost reply : replies)
				{
					Element replyDiv = doc.getElementById("item_" + reply.postId);
					if (replyDiv.getElementsByClass("postbody").size() > 0)
					{
						reply.body = replyDiv.getElementsByClass("postbody").get(0).html();
						reply.date = replyDiv.getElementsByClass("postdate").get(0).ownText();
					}
					else
					{
						reply.body = "AppSpot API Error1";
						reply.date = "";
					}
				}
			}
			
			JSONObject result = new JSONObject();
			
			try {
				result.put("id", res.postId);
				result.put("author", res.author);
				result.put("date", res.date);
				result.put("body", res.body);
				result.put("category", res.category);
				result.put("depth", res.depth);
			} catch (JSONException f) {
				// TODO Auto-generated catch block
				f.printStackTrace();
			}
			
			comments.put(result);
			
			for (ReplyPost reply : replies)
			{
				result = new JSONObject();
    			
    			try {
    				result.put("id", reply.postId);
    				result.put("author", reply.author);
    				result.put("date", reply.date);
    				result.put("body", reply.body);
    				result.put("category", reply.category);
    				result.put("depth", reply.depth);
    			} catch (JSONException f) {
    				// TODO Auto-generated catch block
    				f.printStackTrace();
    			}
    			
    			comments.put(result);
			}
		}
		JSONObject container = new JSONObject();
		try {
			container.put("replies", comments);
		} catch (JSONException g) {
			// TODO Auto-generated catch block
			g.printStackTrace();
		}
		resp.getWriter().print(container.toString());
    }

	private ArrayList<ReplyPost> parseTree(Element replycont, int depth) {
		ArrayList<ReplyPost> replies = new ArrayList<ReplyPost>();
		
		Elements replyChildren = replycont.children();
		for (Element reply : replyChildren)
		{
			ReplyPost res = new ReplyPost();
			res.postId = reply.id().substring(5);
			res.body = "Unset";
			res.depth = depth;
			res.author = reply.getElementsByClass("oneline_user").get(0).ownText();
			
			Set<String> names = reply.child(0).classNames();
			for (String name : names)
			{
				if (name.contains("olmod_"))
					res.category = name.substring(6);
				if (name.contains("fpmod_"))
					res.category = name.substring(6);
			}
			res.date = "Unset";
			
			replies.add(res);
			
			if (reply.getElementsByTag("ul").size() > 0)
			{
				replies.addAll(parseTree(reply.getElementsByTag("ul").get(0),depth + 1));
			}
		}
		
		return replies;
	}
}
